package com.cz.validate.controller;

import com.cz.validate.common.ResultCode;
import com.cz.validate.exception.APIException;
import com.cz.validate.groups.AddUser;
import com.cz.validate.groups.EditUser;
import com.cz.validate.vo.UserVo;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Description todo
 * @Author cz
 * @Date 2022/6/26
 */
@RestController
@RequestMapping("/user/v1")
public class UserController {

    /**
     * 对于@Validated
     * 测试分组校验中，对于新增用户不需要校验其id是否存在，只需要校验用户的账号密码是否满足校验规则
     * <p>
     * `@Validated`会有分组的概念，默认是有一个Default.class,当你的@Validated后面没有加任何校验分组信息的时候默认会加Default分组,
     * 而对于被校验的对象的属性字段，如果你在属性的校验标签里面没有指定分组会添加到默认分组Default里面
     * 所以此处如果不填AddUser.class默认无校验(对象里面所有字段都添加了校验组信息)，需要根据分组来填
     * `@Validated` 加不加@RequestBody都能进行上述分组的基本校验，但是都不能完成嵌套的校验
     * <p>
     * 对于@Valid 参照 CustomerInfoController
     *
     * @param vo     用户
     * @param result 接收异常
     * @return success
     */
    @PostMapping("/add")
    public String addUser(@RequestBody @Validated({AddUser.class}) UserVo vo, BindingResult result) throws APIException, JsonProcessingException {
        //测试全局拦截器
        if (null == vo) {
            throw new APIException(ResultCode.FAILED, "用户信息为空!");
        }
        ObjectMapper mapper = new ObjectMapper();
        System.out.println(result.toString());
        System.out.println(vo);
        if (result.hasErrors()) {
            StringBuilder sb = new StringBuilder();
            for (ObjectError error : result.getAllErrors()) {
                System.out.println(mapper.writeValueAsString("捕获到的单个error对象:" + error));
                System.out.println(error.getDefaultMessage());
                sb.append(error.getDefaultMessage()).append(",");
            }
            throw new APIException(ResultCode.FAILED, sb.toString());
        }
        return "success";
    }

    /**
     * 测试分组校验中，对于修改用户需要校验其对应的id存在，才能去修改对应id用户的账号密码
     *
     * @param vo     用户
     * @param result 接收异常
     * @return success
     * @throws APIException
     */
    @PostMapping("/edit")
    public String editUser(@RequestBody @Validated({EditUser.class}) UserVo vo, BindingResult result) throws APIException, JsonProcessingException {
        //测试全局拦截器
        if (null == vo) {
            throw new APIException(ResultCode.FAILED, "用户信息为空!");
        }
        ObjectMapper mapper = new ObjectMapper();
        System.out.println(result.toString());
        System.out.println(vo);
        if (result.hasErrors()) {
            StringBuilder sb = new StringBuilder();
            for (ObjectError error : result.getAllErrors()) {
                System.out.println(mapper.writeValueAsString("捕获到的单个error对象:" + error));
                System.out.println(error.getDefaultMessage());
                sb.append(error.getDefaultMessage()).append(",");
            }
            throw new APIException(ResultCode.FAILED, sb.toString());
        }
        return "success";
    }
}
